package bfs;

import tree.TreeNode;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 111. 二叉树的最小深度
 * 给定一个二叉树，找出其最小深度。
 * 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
 * 说明：叶子节点是指没有子节点的节点。
 * <p>
 * 限制：
 * 树中节点数的范围在 [0, 10^5] 内
 * -1000 <= Node.val <= 1000
 */
public class MinDepthOfBinaryTree_111 {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int depth = 1;
        // 使用队列来记录bfs每一层遍历的节点
        Queue<TreeNode> q = new LinkedList<>();

        // set记录已经遍历过的节点，实际上从上到下遍历树，不需要记录
//        Set<TreeNode> visited = new HashSet<>();

        q.offer(root);
        while (!q.isEmpty()) {
            // 遍历队列中的所有节点，必须有这句，不然循环中无法更新
            // sz表示一层节点的个数，每遍历完一层之后，会重新计算sz
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                TreeNode curNode = q.poll();
                // 此时说明到达叶子节点
                if (curNode.left == null && curNode.right == null) {
                    return depth;
                }

                if (curNode.left != null) {
                    q.offer(curNode.left);
                }
                if (curNode.right != null) {
                    q.offer(curNode.right);
                }
            }
            // 队列中的节点都在同一层，遍历完之后step才能+1
            depth++;
        }
        return depth;
    }

    public int minDepth2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = minDepth2(root.left);
        int rightDepth = minDepth2(root.right);

        // 如果左子树为空，右子树不为空，则深度为右子树深度+1
        if (root.left == null && root.right != null) {
            return rightDepth + 1;
        }

        // 如果左子树不为空，右子树为空，则深度为左子树深度+1
        if (root.left != null && root.right == null) {
            return leftDepth + 1;
        }

        return Math.min(leftDepth, rightDepth) + 1;
    }

}
